// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package term

import (
	"fmt"
	"gitee.com/go-wares/log/base"
	"gitee.com/go-wares/log/conf"
	"os"
)

// Adapter
// is a component that send logs to the standard output device.
type Adapter struct {
	formatter base.LoggerFormatter
}

// NewAdapter
// creates a new adapter component.
func NewAdapter() *Adapter {
	return &Adapter{
		formatter: &Formatter{},
	}
}

// GetBucket
// returns the bucket component.
func (o *Adapter) GetBucket() *base.Bucket[*base.Item] {
	return nil
}

// GetFormatter
// returns the formatter component.
func (o *Adapter) GetFormatter() base.LoggerFormatter {
	return o.formatter
}

// Log
// send to terminal.
//
//   - os.Stderr
//   - os.Stdout
func (o *Adapter) Log(item *base.Item) {
	var (
		body   = o.formatter.Format(item)
		str    = string(body)
		device = os.Stdout
	)

	// Release
	// when process done.
	defer item.Release()

	// Color
	// rendered around log content.
	if conf.Get().TermAdapter.Color {
		// Yellow text with red background.
		if item.Level.IsFatal() {
			str = fmt.Sprintf("%c[%d;%d;%dm%s%c[0m", 0x1B, 0, 41, 33, str, 0x1B)
			device = os.Stderr
		}

		// Red text.
		if item.Level.IsError() {
			str = fmt.Sprintf("%c[%dm%s%c[0m", 0x1B, 31, str, 0x1B)
			device = os.Stderr
		}

		// Yellow text.
		if item.Level.IsWarn() {
			str = fmt.Sprintf("%c[%dm%s%c[0m", 0x1B, 33, str, 0x1B)
		}

		// Green text.
		if item.Level.IsInfo() {
			str = fmt.Sprintf("%c[%dm%s%c[0m", 0x1B, 32, str, 0x1B)
		}

		// Gray text.
		if item.Level.IsDebug() {
			str = fmt.Sprintf("%c[%dm%s%c[0m", 0x1B, 37, str, 0x1B)
		}
	}

	// Send
	// to terminal.
	_, _ = fmt.Fprintf(device, str+"\n")
}

// SetFormatter
// formats the log to content string.
func (o *Adapter) SetFormatter(formatter base.LoggerFormatter) {
	o.formatter = formatter
}
